package tk.chenyilin.client;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;

import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;

import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;

/**
 * 客户端与服务器的通信的关键类
 * 
 * @author 陈奕霖
 * 
 */
public class Connection extends Thread {
	Client client;
	Socket socket;
	String loginMessage;
	DocumentFactory factory = DocumentFactory.getInstance();

	DefaultListModel<String> model = new DefaultListModel<>();

	ChatUI chat;
	InputStream is;
	OutputStream os;

	/*
	 * xml的类型
	 */
	static final String LOGIN = "1";	//登录信息
	static final String MESSAGE = "2";	//用户发来的消息
	static final String USER_LIST = "3";	//在线用户列表
	static final String EXIT = "4";	//客户端退出

	Connection(Client client) throws Exception {
		this.client = client;
		socket = new Socket(client.hostName, client.port);
		// 获得IO流
		is = socket.getInputStream();
		os = socket.getOutputStream();

		/*
		 * 发送登录信息
		 */
		Document doc = factory.createDocument();
		Element root = factory.createElement("message");
		root.addAttribute("type", LOGIN);
		root.add(factory.createElement("username").addText(client.username));
		doc.add(root);
		loginMessage = doc.asXML();
		os.write(loginMessage.getBytes());
	}

	void chat() throws Exception {
		final Connection connection = this;

		/*
		 * 载入聊天室图形界面
		 */
		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				chat = new ChatUI(connection);
				JOptionPane.showMessageDialog(null, "登陆成功", "成功",
						JOptionPane.INFORMATION_MESSAGE);
				chat.setVisible(true);
			}
		});
	}

	/*
	 * 把发送信息打包成xml
	 */
	String messageToXML(String message) {
		Document doc = factory.createDocument();
		Element root = factory.createElement("message");
		root.addAttribute("type", MESSAGE);
		root.add(factory.createElement("message").addText(message));
		root.add(factory.createElement("user").addText(client.username));
		doc.add(root);
		return doc.asXML();
	}

	// 发送退出信息的方法
	void sendExitMessage() throws Exception {
		Document doc = factory.createDocument();
		Element root = factory.createElement("message");
		root.addAttribute("type", Connection.EXIT);
		root.add(factory.createElement("user").addText(client.username));
		doc.add(root);
		os.write(doc.asXML().getBytes());
	}

	@Override
	public void run() {
		try {
			ExtractInfo exInfo = new ExtractInfo(this);
			while (true) {
				/**
				 * 暂时没有处理数据大小的问题
				 */
				byte[] buf = new byte[5000];
				int len = is.read(buf);
				String message = new String(buf, 0, len); // xml信息
				String response = exInfo.work(message);// 提取相应信息

				/*
				 * 处理相应信息
				 */
				if (response == null) {
				} else if (response
						.equals(/* 命令行遗留 */"Login successfully. Hello, "
								+ client.username + "!")) {
					client.print(response);

					new Thread() {
						public void run() {
							try {
								chat(); // 登陆成功，载入聊天室窗口

							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}.start();

				} else if (response
						.equals(/* 命令行遗留 */"Fail to login, maybe there's one the same name as you.")) {
					JOptionPane.showMessageDialog(null,
							"登陆失败\r\n也许有一个和你名字一样的用户", "失败",
							JOptionPane.ERROR_MESSAGE);
					client.print(response);	/* 命令行遗留 */
					break;
				} else {
					//获取到服务器发来的消息信息，并在TextArea上打印出来
					client.print(response);
					chat.jTextArea1.append(response + "\r\n");
					chat.jTextArea1.selectAll();
				}
			}

		} catch (SocketException e) {
			//如果检测到SocketException则认为与服务器断开连接，关闭程序。
			JOptionPane.showMessageDialog(this.chat, "与服务器的连接断开，程序即将关闭", "警告",
					JOptionPane.WARNING_MESSAGE);
			System.exit(1);
		} catch (Exception e) {

			e.printStackTrace();
		}
	}
}
